package com.flatfish.acvsystem.dao.impl;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.DetachedCriteria;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate4.HibernateTemplate;
import org.springframework.orm.hibernate4.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;

import com.flatfish.acvsystem.dao.IBaseHibernate;
import com.flatfish.acvsystem.vo.PageVO;

/**
 * @author luohuida
 * @Time Mar 7, 2015
 * @Email luo.archer@gmail.com
 * @Description CRUD组件实现类 
 */
@SuppressWarnings("unchecked")
@Repository
public class BaseHibernateImpl extends HibernateDaoSupport implements
		IBaseHibernate {

	private SessionFactory sessionFactory;
	
	@Autowired
	public void setSessionFacotry(SessionFactory sessionFacotry) {     
        super.setSessionFactory(sessionFacotry);     
	}  
	
	/**
	 * @param entity
	 * @return
	 * @throws Exception
	 * @Description <b>增加一个entity对象，返回是否添加成功 </b>
	 * @see com.flatfish.acvsystem.dao.IBaseHibernate#save(java.lang.Object)
	 */
	@Override
	public <T> boolean save(T entity) throws Exception {
		if (null == entity) return false;
		
		boolean bo = false;  
        try {  
            Serializable io = this.getHibernateTemplate().save(entity);  
            if (io != null) 
                bo = true;  
        } catch (Exception e) {  
            bo = false;  
            throw new RuntimeException(e);
        }  
        return bo;  
	}

	/**
	 * @param entity
	 * @return
	 * @throws Exception
	 * @Description <b>添加一个entity对象，返回添加对象的Integer类型的主键 </b>
	 * @see com.flatfish.acvsystem.dao.IBaseHibernate#saveAndGetId4Integer(java.lang.Object)
	 */
	@Override
	public <T> Integer saveAndGetId4Integer(T entity) throws Exception {
		if (null == entity) return null;
		
		Integer id = null;  
        try {  
            id = (Integer) this.getHibernateTemplate().save(entity);  
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
        return id; 
	}

	/**
	 * @param entity
	 * @return
	 * @throws Exception
	 * @Description <b>添加一个对象并且返回该对象的String类型的主键</b>
	 * @see com.flatfish.acvsystem.dao.IBaseHibernate#saveAndGetId4String(java.lang.Object)
	 */
	@Override
	public <T> String saveAndGetId4String(T entity) throws Exception {
		if (null == entity) return null;
		
		String id = null;  
        try {  
            id = (String) this.getHibernateTemplate().save(entity);  
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
        return id; 
	}

	/**
	 * @param hql
	 * @return int 影响行数
	 * @throws Exception
	 * @Description <b>传入hql语句执行 </b>
	 * @see com.flatfish.acvsystem.dao.IBaseHibernate#executeByHql(java.lang.String)
	 */
	@Override
	public int executeByHql(String hql) throws Exception {
		if(null==hql) return -1;
		
		try {  
            return this.getHibernateTemplate().bulkUpdate(hql);           
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
	}

	/**
	 * @param hql
	 * @return List集合 
	 * @throws Exception
	 * @Description <b>传入hql语句执行查询，返回list集合 </b>
	 * @see com.flatfish.acvsystem.dao.IBaseHibernate#findByHql(java.lang.String)
	 */
	
	@Override
	public <T> List<T> findByHql(String hql) throws Exception {
		if(null==hql) return null;
		
		List list = null;  
        try {  
            list = (List<T>) this.getHibernateTemplate().find(hql);  
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
        return list; 
	}

	/**
	 * @param sql
	 * @return int 
	 * @throws Exception
	 * @Description <b>执行原生态的sql语句，添加、删除、修改语句</b>
	 * @see com.flatfish.acvsystem.dao.IBaseHibernate#executeBySql(java.lang.String)
	 */
	@Override
	public int executeBySql(String sql) throws Exception {
		try {  
            return this.getSession().createSQLQuery(sql).executeUpdate();             
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
	}

	/**
	 * @param entity
	 * @return
	 * @throws Exception
	 * @Description <b>修改entity对象，返回是否修改成功</b>
	 * @see com.flatfish.acvsystem.dao.IBaseHibernate#update(java.lang.Object)
	 */
	@Override
	public <T> boolean update(T entity) throws Exception {
		if (null == entity) return false;
		
		boolean bo = false;  
        try {  
            this.getHibernateTemplate().update(entity);  
            bo = true;  
        } catch (Exception e) {  
            bo = false;  
            throw new RuntimeException(e);  
        }  
        return bo;  
	}

	/**
	 * @param hql
	 * @return
	 * @throws Exception
	 * @Description <b>传入hql语句执行修改，返回是否修改成功 </b>
	 * @see com.flatfish.acvsystem.dao.IBaseHibernate#update(java.lang.String)
	 */
	@Override
	public boolean update(String hql) throws Exception {
		if (null == hql) return false;
		
		boolean bo = false;  
        try {  
            int count = this.getHibernateTemplate().bulkUpdate(hql);  
            bo = count > 0 ? true : false;  
        } catch (Exception e) {  
            bo = false;  
            throw new RuntimeException(e);  
        }  
        return bo;  
	}

	/**
	 * @param hql
	 * @return
	 * @throws Exception
	 * @Description <b>执行修改的hql语句，返回修改的行数</b>
	 * @see com.flatfish.acvsystem.dao.IBaseHibernate#updateByHql(java.lang.String)
	 */
	@Override
	public int updateByHql(String hql) throws Exception {
		if (null == hql) return -1;
		
		int count = 0;  
        try {  
            count = this.getHibernateTemplate().bulkUpdate(hql);              
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
        return count;
	}

	/**
	 * @param entity
	 * @return boolean true/false 
	 * @throws Exception
	 * @Description <b>传入一个将要删除的entity对象，返回删除是否成功</b>
	 * @see com.flatfish.acvsystem.dao.IBaseHibernate#delete(java.lang.Object)
	 */
	@Override
	public <T> boolean delete(T entity) throws Exception {
		if(null == entity) return false;
		
		boolean bo = false;  
        try {  
            this.getHibernateTemplate().delete(entity);   
            bo = true;  
        } catch (Exception e) {  
            bo = false;  
            throw new RuntimeException(e);  
        }  
        return bo;  
	}

	/**
	 * @param c
	 * @param id
	 * @return T 返回传入类型对象 
	 * @throws Exception
	 * @Description <b>传入一个entity对象Class和String型主键，返回该对象</b>
	 * @see com.flatfish.acvsystem.dao.IBaseHibernate#getById(java.lang.Class, java.lang.String)
	 */
	@Override
	public <T> T getById(Class<T> c, String id) throws Exception {
		if(null==c || id==null) return null;
		
		 T ety = null;  
	        try {  
	            ety = (T) this.getHibernateTemplate().get(c, id);             
	        } catch (Exception e) {  
	            throw new RuntimeException(e);  
	        }  
	        return ety;  
	}

	/**
	 * @param c
	 * @param id
	 * @return T 返回该类型的对象 
	 * @throws Exception
	 * @Description <b> 传入一个entity对象Class和Serializable类型主键，返回该对象</b>
	 * @see com.flatfish.acvsystem.dao.IBaseHibernate#get(java.lang.Class, java.io.Serializable)
	 */
	@Override
	public <T> T get(Class<T> c, Serializable id) throws Exception {
		if(null==c || id==null) return null;
		
		 T ety = null;  
	        try {  
	            ety = (T) this.getHibernateTemplate().get(c, id);             
	        } catch (Exception e) {  
	            throw new RuntimeException(e);  
	        }  
	   return ety;  
	}

	/**
	 * @param hql
	 * @return 对象T 
	 * @throws Exception
	 * @Description <b>传入hql语句，查询对象 </b>
	 * @see com.flatfish.acvsystem.dao.IBaseHibernate#get(java.lang.String)
	 */
	@Override
	public <T> T get(String hql) throws Exception {
		if(null == hql) return null;
		
		T ety = null;  
        try {  
            ety = (T) this.getSession().createQuery(hql).setMaxResults(1).uniqueResult();         
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
        return ety;  
	}

	/**
	 * @param hql
	 * @return List<?> 
	 * @throws Exception
	 * @Description <b>通过hql语句查询List集合 </b>
	 * @see com.flatfish.acvsystem.dao.IBaseHibernate#getList(java.lang.String)
	 */
	@Override
	public <T> List<T> getList(String hql) throws Exception {
		if(null == hql) return null;
		
		List<T> list = null;  
        try {  
             list = (List<T>) this.getHibernateTemplate().find(hql);        
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
        return list;  
	}

	/**
	 * @param hql
	 * @return 是否删除成功
	 * @throws Exception
	 * @Description <b>传入删除的hql语句，删除记录</b>
	 * @see com.flatfish.acvsystem.dao.IBaseHibernate#delete(java.lang.String)
	 */
	@Override
	public boolean delete(String hql) throws Exception {
		if(null==hql) return false;
		
		try {  
            return this.executeByHql(hql) > 0 ? true : false;  
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
	}

	/**
	 * @param c
	 * @return list集合
	 * @throws Exception
	 * @Description <b>动态查询</b>
	 * @see com.flatfish.acvsystem.dao.IBaseHibernate#getList(java.lang.Class)
	 */
	@Override
	public <T> List<T> getList(Class<T> c) throws Exception {
		if(null==c) return null;
		
		List<T> list = null;  
        try {  
            this.getHibernateTemplate().findByCriteria(DetachedCriteria.forClass(c));  
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
        return list; 
	}

	/**
	 * @param hql
	 * @param obj
	 * @return 返回list集合 
	 * @throws Exception
	 * @Description <b>传入hql查询语句和object数组类型的参数，返回查询list集合 </b>
	 * @see com.flatfish.acvsystem.dao.IBaseHibernate#getList(java.lang.String, java.lang.Object[])
	 */
	@Override
	public <T> List<T> getList(String hql, Object[] obj) throws Exception {
		if(null==hql || null==obj) return null;
		
		List<T> list = null;  
        try {  
             list = (List<T>) this.getHibernateTemplate().find(hql, obj);       
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
        return list;  
	}

	/**
	 * @param queryHql
	 * @param queryCountHql
	 * @param firstResult
	 * @param maxResult
	 * @return List返回集合 集合0保存查询结果、集合1保存总记录条数 
	 * @throws Exception
	 * @Description <b>传入查询语句、查询总条数（总记录）的hql语句、当前页数、每页显示调试数；返回查询后的list集合； 
     * list集合保存总记录调试和记录结果 </b>
	 * @see com.flatfish.acvsystem.dao.IBaseHibernate#showPage(java.lang.String, java.lang.String, int, int)
	 */
	@Override
	public List<?> showPage(String queryHql, String queryCountHql,
			int firstResult, int maxResult) throws Exception {
		if(null==queryHql || null==queryCountHql) return null;
		
		List<Object> list = new ArrayList<Object>();  
        try {  
            Session session = this.getSession();  
            list.add(session.createQuery(queryHql)  
                    .setFirstResult(firstResult).setMaxResults(maxResult).list());   
            list.add(session.createQuery(queryCountHql).setMaxResults(1).uniqueResult());  
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
        return list;  
	}

	/**
	 * @param queryHql
	 * @param queryCountHql
	 * @param page
	 * @throws Exception
	 * @Description <b>传入查询语句和查询总条数（总记录）的hql语句、page分页对象；返回查询后的list集合</b>
	 * @see com.flatfish.acvsystem.dao.IBaseHibernate#showPage(java.lang.String, java.lang.String, com.flatfish.acvsystem.model.Page)
	 */
	@Override
	public <T> void showPage(String queryHql, String queryCountHql, PageVO<T> page)
			throws Exception {
		if(null==queryHql || null==queryCountHql) return;
		
		try {  
            Session session = this.getSession();  
            page.setResult(session.createQuery(queryHql)  
                    .setFirstResult(page.getCurrentPage()).setMaxResults(page.getPageSize()).list());   
            page.setTotalsCount(Integer.parseInt(session.createQuery(queryCountHql).setMaxResults(1).uniqueResult().toString()));  
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
	}

	/**
	 * @param queryCountHql
	 * @param cResult
	 * @param firstResult
	 * @param maxResult
	 * @return List<?> 查询集合 
	 * @throws Exception
	 * @Description <b>分页查询，传入查询count的hql语句和DetachedCriteria动态查询条件进行查询分页 </b>
	 * @see com.flatfish.acvsystem.dao.IBaseHibernate#showPage(java.lang.String, org.hibernate.criterion.DetachedCriteria, int, int)
	 */
	@Override
	public List<?> showPage(String queryCountHql, DetachedCriteria cResult,
			int firstResult, int maxResult) throws Exception {
		if(null==queryCountHql || null==cResult) return null;
		
		List<Object> list = new ArrayList<Object>();  
        try {  
            Session session = this.getSession();  
            list.add(this.getHibernateTemplate().findByCriteria(cResult, firstResult, maxResult));   
            list.add(session.createQuery(queryCountHql).setMaxResults(1).uniqueResult());  
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
        return list;  
	}

	/**
	 * @param queryCountHql
	 * @param cResult
	 * @param page
	 * @throws Exception
	 * @Description <b>分页查询，传入查询的count的hql语句和动态查询DetachedCriteria类及page分页entity</b>
	 * @see com.flatfish.acvsystem.dao.IBaseHibernate#showPage(java.lang.String, org.hibernate.criterion.DetachedCriteria, com.flatfish.acvsystem.model.Page)
	 */
	@Override
	public <T> void showPage(String queryCountHql, DetachedCriteria cResult,
			PageVO<T> page) throws Exception {
		if(null==queryCountHql || null==cResult || null==page) return;
		
		 try {  
	            Session session = this.getSession();  
	            page.setResult((List<T>)this.getHibernateTemplate().findByCriteria(cResult, page.getCurrentPage(), page.getPageSize()));   
	            page.setTotalsCount(Integer.parseInt(session.createQuery(queryCountHql).setMaxResults(1).uniqueResult().toString()));  
	        } catch (Exception e) {  
	            throw new RuntimeException(e);  
	        }  
	}

	/**
	 * @param dc
	 * @return List 
	 * @throws Exception
	 * @Description <b>传入查询条件DetachedCriteria进行查询 </b>
	 * @see com.flatfish.acvsystem.dao.IBaseHibernate#find(org.hibernate.criterion.DetachedCriteria)
	 */
	@Override
	public <T> List<T> find(DetachedCriteria dc) throws Exception {
		if(null==dc) return null;
		
		List<T> list = new ArrayList<T>();  
        try {  
            list = (List<T>) this.getHibernateTemplate().findByCriteria(dc);  
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
        return list;  
	}

	/**
	 * @return Session 
	 * @Description <b>暴露基类session供用户使用 </b>
	 * @see com.flatfish.acvsystem.dao.IBaseHibernate#session()
	 */
	@Override
	public Session getSession() {
		return this.getSessionFactory().getCurrentSession();  
	}

	/**
	 * @return HibernateTemplate 
	 * @Description <b>暴露HibernateTemplate模板，当基类（增删改查组件）方法不够用可以用模板进行操作 </b>
	 * @see com.flatfish.acvsystem.dao.IBaseHibernate#getTemplate()
	 */
	@Override
	public HibernateTemplate getTemplate() {
		return this.getHibernateTemplate();  
	}
	
}
